﻿#ifndef RXNODE_H
#define RXNODE_H

#include "RXEntitySystem_global.h"

#include "RXTree.h"
#include "RXECSDef.h"
#include "RXNodeCreationInfo.h"

/*
每一个前端节点（继承了RXNode的节点）都有一多个对应的后端（继承了ShadowNode的节点）。
后端节点由切面功能维护。前端节点提供接口，具体的实现功能由后端节点和切面功能实现。
前端节点影响后端节点的方式有两个：
1.修改属性。每一个前端节点在修改属性后（必须在元信息中注册，而且必须有Notifier），都会自动向后端节点发出消息
2.发送事件。通过PostEventToShadowNode方法向后端节点发送事件
后端节点影响前端节点的方式只有一个：
1.向前端节点发送事件
*/

class RXWorld;
class RXNodeCreationInfo;

class RXEntitySystem_EXPORT RXNode:public RXTree
{
public:
	REFLECTABLE(RXNode, RXTree);
public:
	RXNode(RXNodeCreationInfo* info);
	~RXNode();
public:
	void SetParent(RXTree* node) override;
	RXECSDef::NodeId GetNodeId() const;

	RXWorld* GetWorld();

	bool IsEnabled() const;//控制实体或组件是否可用，当父节点不可用时，子节点自动不可用
	void SetEnabled(bool v);

	Signal<bool> EnableChanged;

	bool IsGlobalEnabled() const;

	RXECSDef::NodeId GetHeaderNode() const;//头节点，代表该对象是因为另一个对象创建而创建出来的，（和树状图无关系）
	const std::wstring GetCreateName() const;//创建名，代表该对象作为子对象被创建时赋予的名字，它不会随着对象名称改变而改变。用于网络同步时对子对象进行同步
protected:
	void PostEventToShadowNode(ThreadSafe::Event* e);//向该节点的后端节点发送事件
	
	//创建子节点，该函数只能在构造函数内使用。子节点不能存在重名现象
	template<typename T>
	T* CreateDefaultSubObject(RXNode* parent,const wchar_t* objectName) {

		static_assert(std::is_base_of<RXNode,T>::value, "Error T Must Be Derived Of RXNode");

		return dynamic_cast<T*>(CreateDefaultSubObjectImp(parent,objectName,T::staticMetaInfo()));
	}

	RXNode* CreateDefaultSubObjectImp(RXNode* parent,const wchar_t* objectName,MetaInfo meta);

private:
	RXECSDef::NodeId m_id;
	RXECSDef::NodeId m_header;
	RXWorld* m_world;
	bool m_enable;
	std::wstring m_creatName;
	friend class RXWorld;
};




#endif // !RXNODE_H
